<?php

use support\facade\Logger;
use support\Response;
use Tinywan\Jwt\JwtToken;
use const support\ERROR;
use const support\RETCODE_MSGS;
use const support\SUCCESS;
use const support\VERSIONS_PRE;
use const support\VERSIONS_PRO;
use const support\VERSIONS_TEST;

/**
 * 响应正确数据
 * @param array $data
 * @param string $msg
 * @param int $code
 * @param int $memberId
 * @return Response
 */
function buildSuccess(array $data=[], string $msg='ok', int $code=0,int $memberId=0): Response
{
    $data = empty($data)? (object)$data : $data;
    if ($memberId){
        //生成token
        $tokenArr=JwtToken::generateToken([
            'id'=>$memberId
        ]);
        $token=$tokenArr['access_token']??'';
    }
    $info=[
        'code'  =>$code,
        'msg'   =>$msg,
        'data'  =>$data,
        'token' =>$token??'',
        'time'  =>time()
    ];
    Logger::app('响应正确数据','info',$info);
    return json($info);
}

/**
 * 响应错误数据
 * @param int $code
 * @param string $msg
 * @param array $data
 * @param int $memberId
 * @return Response
 */
function buildFail(int $code=ERROR, string $msg='', array $data=[],int $memberId=0): Response
{
    $data = empty($data)? (object)$data : $data;
    $msg=$msg?:((RETCODE_MSGS[$code]??'fail'));
    if ($memberId){
        //生成token
        $tokenArr=JwtToken::generateToken([
            'member_id'=>$memberId
        ]);
        $token=$tokenArr['access_token']??'';
    }
    $info=[
        "code" => $code,
        "msg"  => $msg,
        'data' => $data,
        'token'=> $token??'',
        'time'  =>time()
    ];
    Logger::app('响应错误数据','error',$info);
    return json($info);
}

/**
 * 获取指定数据并初始化数据
 * @param array $columns 指定数据
 * @return array
 */
function getRequestData(array $columns = [],array $exclude=[]): array
{
    Logger::app('请求参数:获取header数据','info',request()->header());
    //获取所有请求数据
    $data=request()->all();
    //统一对数据进行去空格处理
    foreach ($data as &$datum){
        $datum=$datum?trim($datum):$datum;
    }
    //未设置特定取值，则返回全部
    if (!$columns) {
        return $data;
    }
    //定义待返回
    $info = [];
    foreach ($columns as $field => $default) {
        if (is_numeric($field)){
            $value = $data[$default]??'';
            $info[$default] = htmlspecialchars($value, ENT_QUOTES,'UTF-8');
        }else{
            $value = ($data[$field] ?? $default)?:$default;
            $info[$field] = !in_array($field,$exclude)?htmlspecialchars($value, ENT_QUOTES,'UTF-8'):$value;
        }
    }
    Logger::app('请求参数:获取所有请求数据','info',$info);
    return $info;
}

/**
 * 检测是否为生产环境
 * @return bool
 */
function checkRuntimeEnv(): bool
{
    return env('VERSIONS',VERSIONS_PRO)==VERSIONS_PRO;
}

/**
 * 检测是否为测试环境
 * @return bool
 */
function checkTestEnv(): bool
{
    return env('VERSIONS',VERSIONS_PRO)==VERSIONS_TEST;
}

/**
 * 检测是否为预发环境
 * @return bool
 */
function checkPreEnv(): bool
{
    return env('VERSIONS',VERSIONS_PRO)==VERSIONS_PRE;
}

/**
 * 通用分页结构
 * @param array $data
 * @param int $page
 * @param int $limit
 * @param int $total
 * @param array $extends
 * @return array
 */
function commonPagingData(array $data, int $page, int $limit, int $total, array $extends = []): array
{
    $pageInfo = [
        'page' => $page,
        'limit' => $limit,
        'total' => $total,
        'total_page' => ceil($total / $limit),
        'lists' => $data
    ];
    if ($extends) {
        foreach ($extends as $k => $extend) {
            $pageInfo[$k] = $extend;
        }
    }
    return $pageInfo;
}

/**
 * 获取用户ID
 * @return int
 */
function getMemberId(int $memberId=0):int
{
    if ($memberId){
        return $memberId;
    }
    $memberId=request()->member_id??0;
    if (!$memberId){
        if (request()->header('authorization')){
            $memberId = JwtToken::getCurrentId()??0;
        }
    }
    return $memberId;
}

/**
 * 格式化返回数据
 * @param int $code 状态值
 * @param string $msg 提示
 * @param array $data 数据
 * @return array
 */
function formatReturnData(int $code,string $msg='',array $data=[]): array
{
    return [$code,$msg,$data];
}

/**
 * 格式化成功数据
 * @param array $data 数据
 * @return array
 */
function formatReturnSuccessData(array $data=[]): array
{
    return [SUCCESS,RETCODE_MSGS[SUCCESS],$data];
}

/**
 * 生成订单交易流水号
 * @return string
 */
function createOrderTradeNo(): string
{
    return date('YmdHis') . mb_substr(md5(uniqid(microtime(true), true)), 27, 32);
}

//订单号生成规则
function createOrderSn(): string
{
    //日期部分
    $datePart=substr(date('Ymd'),2);
    $timePart=substr(time(),5,-1);
    $randPart=rand_string(4,'0123456789');
    return sprintf("%s%s%s",$datePart,$timePart,$randPart);
}

//微信异步通知成功返回
function wechatNotifySuccess(): Response
{
    $xml = <<<XML
               <xml>
               <return_code><![CDATA[SUCCESS]]></return_code>
               <return_msg><![CDATA[OK]]></return_msg>
               </xml> 
               XML;
    return xml($xml);
}

//微信异步通知成功返回
function wechatNotifyFail($error): Response
{
    $xml = <<<XML
               <xml>
               <return_code><![CDATA[FAIL]]></return_code>
               <return_msg><![CDATA[$error]]></return_msg>
               </xml> 
               XML;
    return xml($xml);
}

//微信异步退款通知解密
function refundDecrypt($encryptedData) {
    $key=config('wechat.wechat_pay.key','');
    // Step 1: 对加密串 A 进行 base64 解码，得到加密串 B
    $decodedData = base64_decode($encryptedData);

    // Step 2: 对商户 key 进行 MD5 计算，得到 32 位小写 key
    $md5Key = md5($key);

    // Step 3: 使用 key 对加密串 B 进行 AES-256-ECB 解密（使用 PKCS7Padding）
    return openssl_decrypt($decodedData, 'AES-256-ECB', $md5Key, OPENSSL_RAW_DATA,'');
}